{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install -U -q langchain langchain-chroma pypdf sentence-transformers langgraph langchain_openai langchain_community pymysql\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Initialize LLM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "llm = ChatOpenAI(model_name=\"gpt-4o\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Summarize Ticket Tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import os\n",
    "FRESHDESK_API_KEY = os.getenv(\"FRESHDESK_API_KEY\")\n",
    "FRESHDESK_URL = os.getenv(\"FRESHDESK_URL\")\n",
    "\n",
    "def get_messages(ticket_id):\n",
    "    url= f'https://{FRESHDESK_URL}.freshdesk.com/api/v2/tickets/{ticket_id}?include=conversations'\n",
    "    headers = {\n",
    "        'Content-Type': 'application/json'\n",
    "    }\n",
    "    auth = (FRESHDESK_API_KEY, 'X')  # Replace 'X' with your actual API key\n",
    "    response = requests.get(url, headers=headers, auth=auth)\n",
    "    return response.json()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def process_messages(messages):\n",
    "    subject = messages['subject']\n",
    "    description = messages['description_text']\n",
    "    conversation = messages['conversations']\n",
    "    messages = \"\"\n",
    "    messages += \"Subject : \" + subject + \"\\n\"\n",
    "    messages += \"User query : \\n\" + description + \"\\n\"\n",
    "    for message in conversation:\n",
    "        if message['incoming']:\n",
    "            messages += \"User Query : \\n\" + message['body_text'] + \"\\n\"\n",
    "        else:\n",
    "            messages += \"Agent Response : \\n\" + message['body_text'] + \"\\n\"\n",
    "    return messages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# message = get_messages(232536)\n",
    "# process_message = process_messages(message)\n",
    "# process_message"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.tools import tool\n",
    "from pydantic import BaseModel\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "\n",
    "class SummarizeToolSchema(BaseModel):\n",
    "    ticket_id: int\n",
    "    \n",
    "@tool(args_schema=SummarizeToolSchema)\n",
    "def summarize_tool(ticket_id: int):\n",
    "    \"\"\"Tool to Summarize Ticket information based on ticket_id provided\n",
    "    `ticket_id`: int\"\"\"\n",
    "    print(\"INSIDE SUMMARIZE NODE\", ticket_id)\n",
    "    # Invoke chain\n",
    "    data = get_messages(ticket_id)\n",
    "    context = process_messages(data)\n",
    "    print(context)\n",
    "    \n",
    "    # Define prompt\n",
    "    prompt = ChatPromptTemplate.from_messages(\n",
    "        [(\"system\", \"\"\"FutureSmart TechStore is committed to being the leading destination for technology enthusiasts worldwide by combining quality, value, and exceptional service. At FutureSmart TechStore, we don’t just sell products—we provide solutions that enhance your lifestyle and work environment. We aim to offer great value to our customers through a range of promotions and discounts, ensuring you get the best deals on the latest technology products.\n",
    "\n",
    "    Our collection includes a wide range of tech products designed to meet the needs of various customers, Our collection includes a wide range of tech products such as Smart Home Solutions (intelligent lighting systems, advanced security devices), Wearable Technology (fitness trackers, smartwatches), Mobile Accessories (chargers, cases, screen protectors), and Computing Peripherals (keyboards, mice, storage devices), designed to meet the needs of various customers, from tech enthusiasts to everyday users.\n",
    "\n",
    "    If the query is not in English, please identify the language and generate a summary of the conversation in English. The response should be generated in the same language as the query.Also mention order id and customer name if present.\\\\n\\\\n{context}. Summarize:\"\"\")]\n",
    "    )\n",
    "\n",
    "    # Instantiate chain\n",
    "    chain = prompt | llm\n",
    "    result = chain.invoke({\"context\": context})\n",
    "    return f\"ticket_id: {ticket_id}\", f\"Ticket Summary: {result.content}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INSIDE SUMMARIZE NODE 100\n",
      "Subject : Order 8\n",
      "User query : \n",
      "Dear Support Team,  I am deeply disappointed that my USB-C Charger (Order #8), expected by Dec 23, did not arrive in time for an important occasion. To make matters worse, I was informed I cannot cancel the order. Please provide an update on when I will receive the item.  I hope for a prompt resolution.  Thank you.\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "('ticket_id: 100',\n",
       " 'Ticket Summary: Subject: Order 8\\n\\nCustomer Name: Not provided\\n\\nThe customer is disappointed because their USB-C Charger (Order #8), expected by December 23, did not arrive in time for an important occasion. They have also been informed that they cannot cancel the order and are requesting an update on when they will receive the item. They are hoping for a prompt resolution.')"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "summarize_tool.invoke({\"ticket_id\":100})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### RAG Tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loaded 14 documents from the folder.\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader\n",
    "from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
    "from typing import List\n",
    "from langchain_core.documents import Document\n",
    "import os\n",
    "\n",
    "def load_documents(folder_path: str) -> List[Document]:\n",
    "    documents = []\n",
    "    for filename in os.listdir(folder_path):\n",
    "        file_path = os.path.join(folder_path, filename)\n",
    "        if filename.endswith('.pdf'):\n",
    "            loader = PyPDFLoader(file_path)\n",
    "        elif filename.endswith('.docx'):\n",
    "            loader = Docx2txtLoader(file_path)\n",
    "        else:\n",
    "            print(f\"Unsupported file type: {filename}\")\n",
    "            continue\n",
    "        documents.extend(loader.load())\n",
    "    return documents\n",
    "\n",
    "folder_path = \"docs/\"\n",
    "documents = load_documents(folder_path)\n",
    "print(f\"Loaded {len(documents)} documents from the folder.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Split the documents into 22 chunks.\n"
     ]
    }
   ],
   "source": [
    "text_splitter = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=1000,\n",
    "    chunk_overlap=200,\n",
    "    length_function=len\n",
    ")\n",
    "\n",
    "splits = text_splitter.split_documents(documents)\n",
    "print(f\"Split the documents into {len(splits)} chunks.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "s:\\FutureSmartAI\\ecommerce_pradeep\\.venv\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "from langchain_huggingface.embeddings import HuggingFaceEmbeddings\n",
    "\n",
    "model_name = \"sentence-transformers/all-MiniLM-L6-v2\"\n",
    "model_kwargs = {'device': 'cpu'}\n",
    "encode_kwargs = {'normalize_embeddings': False}\n",
    "embedding_function = HuggingFaceEmbeddings(\n",
    "    model_name=model_name,\n",
    "    model_kwargs=model_kwargs,\n",
    "    encode_kwargs=encode_kwargs\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\shrey\\AppData\\Local\\Temp\\ipykernel_11656\\3563061202.py:6: LangChainDeprecationWarning: The class `HuggingFaceEmbeddings` was deprecated in LangChain 0.2.2 and will be removed in 1.0. An updated version of the class exists in the :class:`~langchain-huggingface package and should be used instead. To use it run `pip install -U :class:`~langchain-huggingface` and import as `from :class:`~langchain_huggingface import HuggingFaceEmbeddings``.\n",
      "  embedding_function = HuggingFaceEmbeddings(\n",
      "s:\\FutureSmartAI\\ecommerce_pradeep\\.venv\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vector store created and persisted to './chroma_db'\n"
     ]
    }
   ],
   "source": [
    "from langchain_chroma import Chroma\n",
    "\n",
    "collection_name = \"my_collection\"\n",
    "vectorstore = Chroma.from_documents(\n",
    "    collection_name=collection_name,\n",
    "    documents=splits,\n",
    "    embedding=embedding_function,\n",
    "    persist_directory=\"./chroma_db\"\n",
    ")\n",
    "print(\"Vector store created and persisted to './chroma_db'\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# retriever = vectorstore.as_retriever(search_kwargs={\"k\": 2})\n",
    "# retriever_results = retriever.invoke(\"Where is the team of Futuresmart located?\")\n",
    "# print(retriever_results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.tools import tool\n",
    "from pydantic import BaseModel\n",
    "from langchain_chroma import Chroma\n",
    "    \n",
    "class RagToolSchema(BaseModel):\n",
    "    question: str\n",
    "\n",
    "@tool(args_schema=RagToolSchema)\n",
    "def retriever_tool(question: str):\n",
    "    \"\"\"Tool to Retrieve Information from Relevant documents related to FutureSmart Tech Store Company Overview, Contact Information, Payment methods, privacy policy, discount, shipping and warranty policy, etc. Must get all necessary information before replying to a ticket\n",
    "    `question`: str\"\"\"\n",
    "    print(\"INSIDE RETRIEVER NODE\", question)\n",
    "    vectorstore = Chroma(collection_name=\"my_collection\", embedding_function=embedding_function, persist_directory=\"./chroma_db\")\n",
    "    retriever = vectorstore.as_retriever(search_kwargs={\"k\": 5})\n",
    "    retriever_result = retriever.invoke(question)\n",
    "    context = \"\\n\\n\".join(doc.page_content for doc in retriever_result)\n",
    "    \n",
    "    return f\"(context: {context})\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INSIDE RETRIEVER NODE what are different payment methods supported\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'(context: At FutureSmart TechStore, weaimtomakeyourshoppingexperienceasseamlessandsecureaspossible. Wesupport avarietyof payment methodstosuit yourconvenience.\\nSupportedPaymentMethods\\n1. CreditandDebitCards○ Visa○ Mastercard○ AmericanExpress○ RuPay2. DigitalWallets○ Paytm○ PhonePe○ GooglePay○ AmazonPay3. NetBanking○ Supportedforall majorIndianbanksincludingHDFC, ICICI, SBI, AxisBank, andmore.4. UPIPayments○ SeamlesspaymentsusingUnifiedPaymentsInterface(UPI).5. CashonDelivery(COD)○ Availableforselect locationsinIndia.○ MaximumCODlimit: INR10,000.6. EMIOptions○ No-cost EMI andstandardEMI optionsareavailableformajorcredit cards.○ EMI optionsdependonthebankandcardtype.7. BankTransfers○ Direct banktransfersaresupportedforbulkorbusinesspurchases.\\nPaymentSecurity\\n● All onlinetransactionsareprocessedthroughsecureandencryptedgatewaystoensurethesafetyof yourinformation.● Wecomplywiththelatest PCI DSS(Payment CardIndustryDataSecurityStandard)guidelines.\\nImportantNotes\\n\\nAt FutureSmart TechStore, werespect yourprivacyandarecommittedtoprotectingyourpersonal information. ThisPrivacyPolicyoutlineshowwecollect, use, andsafeguardyourdata.\\nInformationWeCollect\\n1. PersonalInformation:○ Name○ Email address○ Phonenumber○ Billingandshippingaddress2. PaymentInformation:○ Credit/Debit carddetails○ UPI orothertransactioninformation(processedsecurelybypayment gateways)3. UsageData:○ Browsingbehavioronourwebsite○ IPaddressanddeviceinformation○ Cookiestoimproveuserexperience\\nHowWeUseYourInformation\\n● Toprocessanddeliveryourorders.● Tocommunicateupdates, promotions, andoffers.● Toimprovewebsitefunctionalityanduserexperience.● Tocomplywithlegal andregulatoryobligations.\\nDataProtection\\n● All sensitivedataisencryptedandstoredsecurely.● WecomplywithGDPRandotherrelevant dataprotectionregulations.● Accesstoyourinformationisrestrictedtoauthorizedpersonnel only.\\nSharingofInformation\\nWedonot sell orrent yourpersonal informationtothirdparties. However, wemaysharedatawith:\\n\\nForanypayment-relatedqueries, feel freetocontact usat support@futuresmarttechstore.comorcall usat +91-XXXXXXXXXX.\\n\\nSharingofInformation\\nWedonot sell orrent yourpersonal informationtothirdparties. However, wemaysharedatawith:\\n● Trustedserviceproviders(e.g., deliverypartners, payment processors).● Legal authoritiesif requiredbylaw.\\nCookiesPolicy\\n● Weusecookiestoenhanceyourbrowsingexperience.● Youcanmanagecookiepreferencesthroughyourbrowsersettings.\\n\\nImportantNotes\\n● Ensureyourpayment methodisactiveandhassufficient balance.● ForCODorders, pleasehavetheexact amount readyasdeliveryagentsmaynot carrychange.● If atransactionfails, donot attempt multipleretries. Contact oursupport teamforassistance.)'"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "retriever_tool.invoke({\"question\": \"what are different payment methods supported\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### NL2SQL Tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.utilities import SQLDatabase\n",
    "import os\n",
    "db_user = os.getenv(\"DB_USER\")\n",
    "db_password = os.getenv(\"DB_PASSWORD\")\n",
    "db_host = os.getenv(\"DB_HOST\")\n",
    "db_name = os.getenv(\"DB_NAME\")\n",
    "db = SQLDatabase.from_uri(f\"mysql+pymysql://{db_user}:{db_password}@{db_host}/{db_name}\",sample_rows_in_table_info=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "\n",
    "def clean_sql_query(text: str) -> str:\n",
    "    \"\"\"\n",
    "    Clean SQL query by removing code block syntax, various SQL tags, backticks,\n",
    "    prefixes, and unnecessary whitespace while preserving the core SQL query.\n",
    "\n",
    "    Args:\n",
    "        text (str): Raw SQL query text that may contain code blocks, tags, and backticks\n",
    "\n",
    "    Returns:\n",
    "        str: Cleaned SQL query\n",
    "    \"\"\"\n",
    "    # print(text)\n",
    "    # Step 1: Remove code block syntax and any SQL-related tags\n",
    "    # This handles variations like ```sql, ```SQL, ```SQLQuery, etc.\n",
    "    block_pattern = r\"```(?:sql|SQL|SQLQuery|mysql|postgresql)?\\s*(.*?)\\s*```\"\n",
    "    text = re.sub(block_pattern, r\"\\1\", text, flags=re.DOTALL)\n",
    "\n",
    "    # Step 2: Handle \"SQLQuery:\" prefix and similar variations\n",
    "    # This will match patterns like \"SQLQuery:\", \"SQL Query:\", \"MySQL:\", etc.\n",
    "    prefix_pattern = r\"^(?:SQL\\s*Query|SQLQuery|MySQL|PostgreSQL|SQL)\\s*:\\s*\"\n",
    "    text = re.sub(prefix_pattern, \"\", text, flags=re.IGNORECASE)\n",
    "\n",
    "    # Step 3: Extract the first SQL statement if there's random text after it\n",
    "    # Look for a complete SQL statement ending with semicolon\n",
    "    sql_statement_pattern = r\"(SELECT.*?;)\"\n",
    "    sql_match = re.search(sql_statement_pattern, text, flags=re.IGNORECASE | re.DOTALL)\n",
    "    if sql_match:\n",
    "        text = sql_match.group(1)\n",
    "\n",
    "    # Step 4: Remove backticks around identifiers\n",
    "    text = re.sub(r'`([^`]*)`', r'\\1', text)\n",
    "\n",
    "    # Step 5: Normalize whitespace\n",
    "    # Replace multiple spaces with single space\n",
    "    text = re.sub(r'\\s+', ' ', text)\n",
    "\n",
    "    # Step 6: Preserve newlines for main SQL keywords to maintain readability\n",
    "    keywords = ['SELECT', 'FROM', 'WHERE', 'GROUP BY', 'HAVING', 'ORDER BY',\n",
    "               'LIMIT', 'JOIN', 'LEFT JOIN', 'RIGHT JOIN', 'INNER JOIN',\n",
    "               'OUTER JOIN', 'UNION', 'VALUES', 'INSERT', 'UPDATE', 'DELETE']\n",
    "\n",
    "    # Case-insensitive replacement for keywords\n",
    "    pattern = '|'.join(r'\\b{}\\b'.format(k) for k in keywords)\n",
    "    text = re.sub(f'({pattern})', r'\\n\\1', text, flags=re.IGNORECASE)\n",
    "\n",
    "    # Step 7: Final cleanup\n",
    "    # Remove leading/trailing whitespace and extra newlines\n",
    "    text = text.strip()\n",
    "    text = re.sub(r'\\n\\s*\\n', '\\n', text)\n",
    "    # print(text)\n",
    "    return text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.tools import QuerySQLDatabaseTool\n",
    "\n",
    "def get_sql_chain():\n",
    "    execute_query = QuerySQLDatabaseTool(db=db)\n",
    "    \n",
    "    \n",
    "    prompt = ChatPromptTemplate.from_messages(\n",
    "        [(\"system\", \"\"\"You are a MySQL expert. Given an input question, create a syntactically correct MySQL query to run. Use the LIKE operator for all string matching queries, ensuring proper use of wildcards (% or _) for partial matches. Only use = operator when quering for order_id or product_id column.\n",
    "        Here is the relevant table information: {table_info}\"\"\"),\n",
    "        (\"human\", \"{human_message}\" )]\n",
    "    )\n",
    "    write_query = prompt | llm | StrOutputParser()\n",
    "\n",
    "    chain = (\n",
    "        RunnablePassthrough.assign(query=write_query | RunnableLambda(clean_sql_query)).assign(\n",
    "            result=itemgetter(\"query\") | execute_query\n",
    "        )\n",
    "    )\n",
    "    return chain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "from operator import itemgetter\n",
    "import re\n",
    "from langchain_core.output_parsers import StrOutputParser\n",
    "from langchain_core.prompts import PromptTemplate\n",
    "from langchain_core.runnables import RunnablePassthrough, RunnableLambda\n",
    "from typing import Optional \n",
    "\n",
    "class SQLToolSchema(BaseModel):\n",
    "    question: str\n",
    "    order_id: Optional[str] = \"\"\n",
    "    product_id: Optional[str] = \"\"\n",
    "\n",
    "@tool(args_schema=SQLToolSchema)\n",
    "def nl2sql_tool(question: str, order_id: Optional[str] = \"\", product_id: Optional[str] = \"\"):\n",
    "  \"\"\"Tool to get Product detail or Order status. Must get Order details before responding to a ticket\n",
    "  `question`: str, `order_id`: str, `product_id`: str\"\"\"\n",
    "\n",
    "  print(\"INSIDE NL2SQL TOOL\", question)\n",
    "  chain = get_sql_chain()\n",
    "  table_info = db.get_table_info() \n",
    "  human_message = f\"question: {question}, order id: {order_id}, product_id: {product_id}, sql_query:\" \n",
    "  print(\"human_message:\", human_message)\n",
    "  response = chain.invoke({\"human_message\": human_message, \"table_info\":table_info})\n",
    "  return f\"Product detail and Order status: {response['result']}, SQL Query used:{response['query']}\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INSIDE NL2SQL TOOL Check Order status\n",
      "human_message: question: Check Order status, order id: 8, product_id: , sql_query:\n",
      "Question: Check Order status\n",
      "Answer: Product detail and Order status: [('Processing',)], SQL Query used:SELECT order_status \n",
      "FROM Orders \n",
      "WHERE order_id = 8;\n"
     ]
    }
   ],
   "source": [
    "question = \"Check Order status\"\n",
    "order_id = \"8\"\n",
    "product_id = \"\"\n",
    "result = nl2sql_tool.invoke({\"question\": question,\"order_id\": order_id, \"product_id\":product_id})\n",
    "print(f\"Question: {question}\")\n",
    "print(f\"Answer: {result}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reply Tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_reply(ticket_id, body):\n",
    "    try:\n",
    "        url = f'https://{FRESHDESK_URL}.freshdesk.com/api/v2/tickets/{ticket_id}/reply'\n",
    "        headers = {\n",
    "            'Content-Type': 'application/json'\n",
    "        }\n",
    "        auth = (FRESHDESK_API_KEY, 'X')  # Replace 'X' with your actual API key\n",
    "        data = {\n",
    "            \"body\": body\n",
    "        }\n",
    "        response = requests.post(url, headers=headers, auth=auth, json=data)\n",
    "        return response.json()\n",
    "    except Exception as e:\n",
    "        print(\"Error in create_reply : \", e)\n",
    "        return \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.tools import tool\n",
    "from pydantic import BaseModel\n",
    "\n",
    "class ReplyToTicket(BaseModel):\n",
    "    information: str\n",
    "    ticket_id: str\n",
    "    \n",
    "@tool(args_schema=ReplyToTicket)\n",
    "def reply_to_ticket_tool(information: str, ticket_id: str):\n",
    "    \"\"\"Tool that will send a reply to customer with a ticket id\n",
    "    `information`: str, \n",
    "    `ticket_id`: str\"\"\"\n",
    "    \n",
    "    print(\"INSIDE REPLY TOOL\", ticket_id)\n",
    "    import datetime\n",
    "    current_time = datetime.date.today()\n",
    "    prompt = ChatPromptTemplate.from_messages([\n",
    "        (\"system\", f\"\"\"\n",
    "**Introduction to FutureSmart TechStore:**\n",
    "FutureSmart TechStore is a leading retailer specializing in cutting-edge technology products, ensuring you have access to the latest innovations to meet your needs. We pride ourselves on our customer service and offer support in multiple languages to cater to our diverse clientele. Our inventory includes a wide range of electronics, smart home devices, and accessories, all curated to enhance your tech lifestyle.\n",
    "\n",
    "**Guidelines for Responding to Customer Queries:**\n",
    "\n",
    "Current date and time is \"{current_time}. Use the current date and time for generating time sensitive responses.\n",
    "**Identify Language and Respond in English:**\n",
    "   Analyze the language of the customer's query to ensure accurate understanding. While responding, provide all replies in English to maintain consistency.\n",
    "\n",
    "**Order Information and Query Specifics:**\n",
    "   Utilize provided order details to address specific customer queries accurately. Ensure responses are tailored to address only the aspects of the order that the customer has inquired about. Do not include unnecessary order details unless requested.\n",
    "\n",
    "By adhering to these guidelines, ensure that your responses are informative, accurate, and aligned with FutureSmart TechStore's commitment to customer satisfaction. Remember to always maintain a friendly and professional tone in all communications.\n",
    "\n",
    "You are an AI assistant tasked with crafting a professional customer reply in Gmail format. Mention FutureSmart TechStore Support, 9876543210 Phone number. Avoid placeholders or incomplete information, and provide clear, actionable steps to resolve the issue\"\"\"),\n",
    "        (\"human\", \"context: {information}\" )\n",
    "    ])\n",
    "    chain = prompt | llm | StrOutputParser()\n",
    "    body = chain.invoke({\"information\": information})\n",
    "    res = {}\n",
    "    res = create_reply(ticket_id, body)\n",
    "    return body, f\"reply id: {res.get('id')}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INSIDE REPLY TOOL 100\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "('Subject: Resolution for Your Order Delay - Order ID: 8\\n\\nDear Valued Customer,\\n\\nI hope this message finds you well. I am writing on behalf of FutureSmart TechStore to address your concerns regarding your order, and I sincerely apologize for any disappointment and inconvenience caused by the delayed delivery of your ring, especially on such a significant occasion as your wedding.\\n\\nI understand that not receiving your ring in time for your wedding on July 3rd was disheartening. Please rest assured that we are committed to resolving this matter promptly.\\n\\nRegarding your request for the delivery status, I have checked the details of your order (Order ID: 8). Your ring is currently in transit and is expected to arrive within the next few days. We are doing everything we can to expedite the process and ensure it reaches you as soon as possible.\\n\\nWhile I understand that this does not compensate for the missed moment, I want to assure you that we are dedicated to making things right. As a gesture of goodwill, we would like to offer you a discount on your next purchase or another form of compensation as per your preference. Please let us know your choice, and we will arrange it accordingly.\\n\\nIf there is anything else we can do to assist you further, please do not hesitate to reach out to us. You can contact FutureSmart TechStore Support at 9876543210, and we will be more than happy to help.\\n\\nThank you for your understanding and patience in this matter. We value your trust in FutureSmart TechStore and are committed to providing you with the best possible service.\\n\\nWarm regards,\\n\\n[Your Name]  \\nFutureSmart TechStore Support  \\n9876543210',\n",
       " 'reply id: 11000010366602')"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "information = \"The customer is disappointed because they did not receive their ring in time for their wedding on July 3, causing sadness as the event occurred without it. They were informed that they cannot cancel the order and are requesting information on when they will receive the ring. The customer stresses their disappointment and seeks a resolution. Order ID is 8. Customer name is not provided.\"\n",
    "ticket_id = \"100\"\n",
    "reply_to_ticket_tool.invoke({\"information\": information, \"ticket_id\": ticket_id})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Langgraph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = [summarize_tool, retriever_tool, nl2sql_tool, reply_to_ticket_tool]\n",
    "llm_with_tools = llm.bind_tools(tools)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import Annotated\n",
    "\n",
    "# from langchain_core.messages import BaseMessage\n",
    "from typing_extensions import TypedDict\n",
    "\n",
    "from langgraph.graph import StateGraph\n",
    "from langgraph.graph.message import add_messages\n",
    "from langgraph.prebuilt import ToolNode, tools_condition\n",
    "from langgraph.checkpoint.memory import MemorySaver\n",
    "\n",
    "memory = MemorySaver()\n",
    "# graph = builder.compile(checkpointer=memory)\n",
    "# Setting up the graph state\n",
    "class State(TypedDict):\n",
    "    messages: Annotated[list, add_messages]\n",
    "\n",
    "\n",
    "\n",
    "def chatbot(state: State):\n",
    "    return {\"messages\": [llm_with_tools.invoke(state[\"messages\"])]}\n",
    "\n",
    "graph_builder = StateGraph(State)\n",
    "graph_builder.add_node(\"chatbot\", chatbot)\n",
    "\n",
    "tool_node = ToolNode(tools=tools)\n",
    "graph_builder.add_node(\"tools\", tool_node)\n",
    "\n",
    "graph_builder.add_conditional_edges(\n",
    "    \"chatbot\",\n",
    "    tools_condition,\n",
    ")\n",
    "# Any time a tool is called, we return to the chatbot to decide the next step\n",
    "graph_builder.add_edge(\"tools\", \"chatbot\")\n",
    "graph_builder.set_entry_point(\"chatbot\")\n",
    "graph = graph_builder.compile(checkpointer=memory)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "\n",
    "try:\n",
    "    display(Image(graph.get_graph().draw_mermaid_png()))\n",
    "except Exception:\n",
    "    # You can put your exception handling code here\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "User:  analyse ticket id 100\n",
      "Assistant: \n",
      "INSIDE SUMMARIZE NODE 100\n",
      "Subject : Order 8\n",
      "User query : \n",
      "Dear Support Team,  I am deeply disappointed that my USB-C Charger (Order #8), expected by Dec 23, did not arrive in time for an important occasion. To make matters worse, I was informed I cannot cancel the order. Can you please verify whether I can get a refund or not. Please provide an update on when I will receive the item.  I hope for a prompt resolution.  Thank you.\n",
      "\n",
      "Assistant: [\"ticket_id: 100\", \"Ticket Summary: Summary: The customer, who is disappointed, mentions that their USB-C Charger (Order #8), expected by December 23, did not arrive on time. They express frustration over being unable to cancel the order and request a verification on whether they can receive a refund. Additionally, they seek an update on the delivery status of the item and hope for a prompt resolution. Customer Name is not provided.\"]\n",
      "Assistant: \n",
      "INSIDE NL2SQL TOOL Get the delivery status and estimated delivery date for order #8\n",
      "INSIDE RETRIEVER NODE Can a customer receive a refund for a delayed order, and what is the process for cancellation and refund according to the company's policy?\n",
      "human_message: question: Get the delivery status and estimated delivery date for order #8, order id: 8, product_id: , sql_query:\n",
      "Assistant: (context: ● Software, CDs, orDVDsthat havebeenopened.● Itemsmarkedas\"Final Sale\"or\"Non-Returnable\"at thetimeof purchase.● Gift cardsorpromotional items.\n",
      "HowtoInitiateaReturn\n",
      "1. Contact Us: Reachout toourcustomerserviceteamviaemail atsupport@futuresmarttechstore.comorcall usat +91-XXXXXXXXXXwithyourorderdetails.2. Approval: Onceyourreturnrequest isapproved, youwill receiveaReturnMerchandiseAuthorization(RMA)numberanddetailedinstructions.3. ShiptheItem: Packtheitemsecurely, includetheRMAnumber, andsendit toourreturnaddress: FutureSmart TechStoreReturnsDepartment Mumbai, IndiaPIN: 400001\n",
      "RefundProcess\n",
      "● Refundswill beprocessedoncethereturneditemisinspectedandapproved.● Refundswill beissuedtotheoriginal payment methodwithin7-10businessdaysafterapproval.● Shippingfeesarenon-refundableunlessthereturnisduetoamistakeonourpart (e.g.,wrongordefectiveitem).\n",
      "ExchangePolicy\n",
      "\n",
      "TrackingYourOrder\n",
      "● All ordersareshippedwithatrackingnumber. Youcanmonitortheprogressof yourdeliveryviathelinkprovidedinyourconfirmationemail.\n",
      "UndeliverablePackages\n",
      "● If apackageisdeemedundeliverableduetoanincorrect address, recipientunavailability, orotherreasons, it will bereturnedtoourwarehouse. Insuchcases:○ Are-shippingfeemayapply.○ Refundswill excludeshippingcharges.\n",
      "DamagedorMissingItems\n",
      "● If yourorderarrivesdamagedorincomplete, pleasecontact ourcustomerserviceteamwithin48hoursof deliverywiththefollowingdetails:○ Ordernumber\n",
      "\n",
      "At FutureSmart TechStore, westrivetoensurecustomersatisfactionwitheverypurchase. Ifyouarenot completelysatisfiedwithyourorder, weofferahassle-freereturnpolicytomaketheprocessassmoothaspossible.\n",
      "EligibilityforReturns\n",
      "● Productscanbereturnedwithin30daysof receipt.● Itemsmust beintheiroriginal condition, unused, andintheoriginal packagingwithalltags, manuals, andaccessoriesincluded.● Returnsareapplicableforitemsthat aredamaged, defective, ornot asdescribed.\n",
      "Non-ReturnableItems\n",
      "Thefollowingitemsarenot eligibleforreturn:\n",
      "● Software, CDs, orDVDsthat havebeenopened.● Itemsmarkedas\"Final Sale\"or\"Non-Returnable\"at thetimeof purchase.● Gift cardsorpromotional items.\n",
      "HowtoInitiateaReturn\n",
      "\n",
      "HowtoClaimWarranty\n",
      "1. ContactCustomerSupport: Reachout tousat support@futuresmarttechstore.comorcall usat +91-XXXXXXXXXXwithyourorderdetailsandadescriptionof theissue.2. ProvideProofofPurchase: Ensureyouhaveacopyof yourinvoiceorreceipt.3. InspectionandApproval: Ourteamwill guideyouthroughtheinspectionprocess. Ifeligible, theproduct will eitherberepairedorreplacedasperthemanufacturer’spolicy.\n",
      "ManufacturerWarrantyProcess\n",
      "● Someproductsmayrequiredirect warrantyclaimswiththemanufacturer. Insuchcases,ourteamwill assist youincontactingthemanufacturer’sservicecenter.\n",
      "ExtendedWarranty\n",
      "● Extendedwarrantyplansareavailableforselect products. Theseplanscanbepurchasedduringcheckout foraddedcoveragebeyondthestandardwarrantyperiod.\n",
      "ImportantNotes\n",
      "● Warrantyclaimsaresubject toapproval basedonthemanufacturer’stermsandconditions.● Shippingcostsforwarrantyclaimsmaybebornebythecustomerunlessstatedotherwise.\n",
      "\n",
      "At FutureSmart TechStore, wearecommittedtodeliveringyourordersswiftlyandsecurely.Belowarethedetailsof ourshippingpoliciestoensureasmoothandtransparent shoppingexperience.\n",
      "ShippingLocations\n",
      "● WecurrentlyshipacrossIndia.● International shippingisnot availableat thistime.\n",
      "ShippingCharges\n",
      "● StandardShipping: FreeforordersaboveINR1,000.○ OrdersbelowINR1,000will incurashippingfeeof INR50.● ExpressShipping: Availableat INR150foreligiblelocations.\n",
      "DeliveryTimeframes\n",
      "● StandardShipping: 3-7businessdays.● ExpressShipping: 1-3businessdays.● Deliverytimesmayvarybasedonlocationandavailability.\n",
      "OrderProcessing\n",
      "● Ordersareprocessedwithin24-48hoursof payment confirmation(excludingweekendsandholidays).● Youwill receiveaconfirmationemail withtrackingdetailsonceyourorderisshipped.\n",
      "TrackingYourOrder\n",
      "● All ordersareshippedwithatrackingnumber. Youcanmonitortheprogressof yourdeliveryviathelinkprovidedinyourconfirmationemail.\n",
      "UndeliverablePackages)\n",
      "Assistant: \n",
      "INSIDE REPLY TOOL 100\n",
      "Assistant: [\"Subject: Update on Your Order and Assistance with FutureSmart TechStore\\n\\nDear [Customer's Name],\\n\\nThank you for reaching out to us at FutureSmart TechStore. We sincerely apologize for any inconvenience you may have experienced with your order. Below is an update on your order status and information on our refund and cancellation policy:\\n\\n1. **Order Delivery Status:**\\n   - Your order is currently in 'Processing' status. We anticipate that it will be delivered to you by December 13, 2024.\\n\\n2. **Refund and Cancellation Policy:**\\n   - If your product does not arrive on time or if you are not satisfied with it, you are eligible to initiate a return and refund process.\\n   - To start a return, please contact our customer service team via email at support@futuresmarttechstore.com or by calling us at +91-9876543210. Make sure to include your order details in your communication.\\n   - Once your return request is approved, you will receive a Return Merchandise Authorization (RMA) number along with detailed instructions for the return process.\\n   - Refunds will be processed after the returned item is inspected and approved and will be issued to the original payment method within 7-10 business days following approval.\\n   - Please note that shipping fees are non-refundable unless the return is due to an error on our part, such as a wrong or defective item.\\n\\nWe are committed to resolving this issue to your satisfaction and are here to assist you further if needed. Please let us know how you would like to proceed. Once again, we apologize for any inconvenience this may have caused.\\n\\nThank you for choosing FutureSmart TechStore. We look forward to serving you better.\\n\\nBest regards,\\n\\nFutureSmart TechStore Support  \\nContact: +91-9876543210  \\nEmail: support@futuresmarttechstore.com\", \"reply id: 11000010366621\"]\n"
     ]
    }
   ],
   "source": [
    "config = {\"configurable\": {\"thread_id\": \"10\"}}\n",
    "\n",
    "while True:\n",
    "    user_input = input(\"User: \")\n",
    "    print(\"User: \", user_input)\n",
    "    if user_input.lower() in [\"quit\", \"exit\", \"q\"]:\n",
    "        print(\"Goodbye!\")\n",
    "        break\n",
    "\n",
    "    # Process user input through the LangGraph\n",
    "    for event in graph.stream({\"messages\": [(\"user\", user_input)]}, config):\n",
    "        for value in event.values():\n",
    "            print(\"Assistant:\", value[\"messages\"][-1].content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
